package com.iflyun.redis.dao.impl;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.ScanOptions.ScanOptionsBuilder;


import com.iflyun.redis.dao.RedisDao;
import com.iflyun.redis.entity.Redis;

public class RedisDaoImpl implements RedisDao {

	@Resource(name = "redisTemplate")
	protected RedisTemplate<String, Redis> redisTemplate;
	
	
	
	@Override
	public void add(final Redis redis) {
		 redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                connection.set(
                		redisTemplate.getStringSerializer().serialize(redis.getKey()),
                        redisTemplate.getStringSerializer().serialize(redis.getValue())
                         );
                return null;
            }
	    });
	}

	@Override
	public boolean add(final List<Redis> list) {
	 return redisTemplate.execute(new RedisCallback<Boolean>() {  
            public Boolean doInRedis(RedisConnection connection)  
                    throws DataAccessException {   
                for (Redis redis : list) {  
                	 connection.set(
                        redisTemplate.getStringSerializer().serialize(redis.getKey()),
                        redisTemplate.getStringSerializer().serialize(redis.getValue())
                      );
                }  
                return true;  
            }  
        }, false, true);   
	}

	@Override
	public void delete(String key) {
		List<String> list = new ArrayList<>();  
	    list.add(key);  
	    delete(list);  
		
	}

	@Override
	public void delete(List<String> keys) {
		redisTemplate.delete(keys);  
		
	}

	@Override
	public boolean update(final Redis redis) {
		    String key = redis.getKey();  
	        if (get(key) == null) {  
	            throw new NullPointerException("数据行不存在, key = " + key);  
	        }  
	        return redisTemplate.execute(new RedisCallback<Boolean>() {  
	            public Boolean doInRedis(RedisConnection connection)  
	                    throws DataAccessException {  
	            	connection.set(
	                        redisTemplate.getStringSerializer().serialize(redis.getKey()),
	                        redisTemplate.getStringSerializer().serialize(redis.getValue())
	                      ); 
	                return true;  
	            }  
	        });  
	}

	@Override
	public Redis get(final String keyId) {
		 return redisTemplate.execute(new RedisCallback<Redis>() {  
	            public Redis doInRedis(RedisConnection connection)  
	                    throws DataAccessException { 
	            	
	            	 byte[] value=connection.get(redisTemplate.getStringSerializer().serialize(keyId));  
	                if (value == null) {  
	                    return null;  
	                }  
	                String v = redisTemplate.getStringSerializer().deserialize(value);  
	                return new Redis(keyId, v);  
	            }  
	        });  
	}

	@Override
	public void addTtl(final Redis redis,final long time) {
		 redisTemplate.execute(new RedisCallback<Object>() {
	            @Override
	            public Object doInRedis(RedisConnection connection) throws DataAccessException {
	                connection.set(
	                		redisTemplate.getStringSerializer().serialize(redis.getKey()),
	                        redisTemplate.getStringSerializer().serialize(redis.getValue())
	                         );
	                connection.expire(redisTemplate.getStringSerializer().serialize(redis.getKey()), time);
	              
	                return null;
	               
	               // connection.sca
	            }
		    });
	}

	@Override
	public List<String> getLike(final String match,final long count) {
		final List<String> list=new ArrayList<>();
		List<String> result = redisTemplate.execute(new RedisCallback<List<String>>() {  
	            public List<String> doInRedis(RedisConnection connection)  
	                    throws DataAccessException { 
	            	 ScanOptionsBuilder sob=new  ScanOptionsBuilder();
	                 sob.count(count);
	                 sob.match(match);
	                 ScanOptions options= sob.build();
	                 Cursor<byte[]> keys=connection.scan(options);
	                 while (keys.hasNext()) {
	                	String key = redisTemplate.getStringSerializer().deserialize(keys.next());  
	                	list.add(key);
					}
	                return list;  
	            }  
	        });  
	        return result;
	}
	
	
	

	

}
